home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / sbin / update-xmlcatalog < prev    next >
Text File  |  2008-11-06  |  17KB  |  627 lines

  1. #!/usr/bin/perl
  2. ## ----------------------------------------------------------------------
  3. ## Debian update-xmlcatalog
  4. ## ----------------------------------------------------------------------
  5. ## Copyright (c) 2003-2004 Ardo van Rangelrooij
  6. ##
  7. ## This is free software; see the GNU General Public Licence version 2
  8. ## or later for copying conditions.  There is NO warranty.
  9. ## ----------------------------------------------------------------------
  10.  
  11. =head1 NAME
  12.  
  13. update-xmlcatalog - maintain XML catalog files
  14.  
  15. =head1 SYNOPSIS
  16.  
  17. B<update-xmlcatalog> B<--add> B<--root> S<B<--package> I<package>>
  18. S<B<--type> I<type>> S<B<--id> I<id>>
  19.  
  20. B<update-xmlcatalog> B<--del> B<--root> S<B<--package> I<package>>
  21. S<B<--type> I<type>> S<B<--id> I<id>>
  22.  
  23. B<update-xmlcatalog> B<--add> S<B<--package> I<package>> S<B<--local>
  24. I<local>> S<B<--type> I<type>> S<B<--id> I<id>>
  25.  
  26. B<update-xmlcatalog> B<--del> S<B<--package> I<package>> S<B<--local>
  27. I<local>> S<B<--type> I<type>> S<B<--id> I<id>>
  28.  
  29. B<update-xmlcatalog> B<--add> S<B<--local> I<local>> S<B<--file>
  30. I<file>> S<B<--type> I<type>> S<B<--id> I<id>>
  31.  
  32. B<update-xmlcatalog> B<--del> S<B<--local> I<local>> S<B<--file>
  33. I<file>> S<B<--type> I<type>> S<B<--id> I<id>>
  34.  
  35. B<update-xmlcatalog> B<--help>
  36.  
  37. =head1 DESCRIPTION
  38.  
  39. B<update-xmlcatalog> add entries to and removes entries from the root
  40. XML catalog file, a package XML catalog file or a local XML catalog
  41. file.
  42.  
  43. =head1 OPTIONS
  44.  
  45. =over 4
  46.  
  47. =item B<--add>
  48.  
  49. Adds the entry to the root XML catalog file, a package XML catalog
  50. file or a local XML catalog file.  If the XML catalog file does not
  51. exist yet, it is automatically created.
  52.  
  53. =item B<--del>
  54.  
  55. Deletes the entry from the root XML catalog file, the package XML
  56. catalog file or the local XML catalog file.  A resulting empty XML
  57. catalog is not automatically deleted from the filesystem.
  58.  
  59. =item B<--file> I<file>
  60.  
  61. Indicates a local filename.
  62.  
  63. =item B<--id> I<id>
  64.  
  65. Indicates the XML catalog file entry identifier.
  66.  
  67. =item B<--local> I<local>
  68.  
  69. Indicates a local XML catalog file.
  70.  
  71. =item B<--package> I<package>
  72.  
  73. Indicates a package XML catalog file.
  74.  
  75. =item B<--root>
  76.  
  77. Indicates the root XML catalog file.
  78.  
  79. =item B<--type> I<type>
  80.  
  81. Indicates the XML catalog file entry type (public, system, uri).
  82.  
  83. =item B<--help>
  84.  
  85. Displays the usage information.
  86.  
  87. =back
  88.  
  89. =head1 NOTES
  90.  
  91. B<update-xmlcatalog> is the de-facto standard tool to be used to
  92. maintain XML catalog files on a Debian system, similar to that
  93. L<update-catalog(8)> is the standard tool to be used to main SGML
  94. catalog files on a Debian system.  A Debian XML Policy document to
  95. this effect is currently under development.
  96.  
  97. B<update-xmlcatalog> and L<xmlcatalog(1)> are incompatible.  The
  98. former has an internal database of all the entries in all the XML
  99. catalog files it maintains and regenerates the indicated XML catalog
  100. file completely from scratch upon an update.  The latter updates the
  101. indicated XML catalog file directly.  This means that any change made
  102. to an XML catalog file using L<xmlcatalog(1)> is overwritten the next
  103. time that XML catalog file is updated using B<update-xmlcatalog>.
  104.  
  105. =head1 SEE ALSO
  106.  
  107. F</usr/share/doc/xml-core/README.Debian>
  108.  
  109. =head1 AUTHOR
  110.  
  111. B<Ardo van Rangelrooij> E<lt>ardo@debian.orgE<gt>
  112.  
  113. =cut
  114.  
  115. ## ----------------------------------------------------------------------
  116. use strict;
  117.  
  118. ## ----------------------------------------------------------------------
  119. use File::Spec;
  120. use Getopt::Long;
  121.  
  122. ## ----------------------------------------------------------------------
  123. $0  =~ m|[^/]+$|;
  124.  
  125. ## ----------------------------------------------------------------------
  126. my $name = $&;
  127.  
  128. ## ----------------------------------------------------------------------
  129. use vars qw( $catalog_data $catalog_data_dir );
  130. use vars qw( $catalog $catalog_dir );
  131. use vars qw( %catalog $key $entry );
  132.  
  133. ## ----------------------------------------------------------------------
  134. $catalog_data_dir = '/var/lib/xml-core';
  135. $catalog_dir      = '/etc/xml';
  136.  
  137. ## ----------------------------------------------------------------------
  138. use vars qw( $add );
  139. use vars qw( $del );
  140. use vars qw( $file );
  141. use vars qw( $help );
  142. use vars qw( $local );
  143. use vars qw( $package );
  144. use vars qw( $root );
  145. use vars qw( $type $id );
  146. use vars qw( $verbose );
  147.  
  148. ## ----------------------------------------------------------------------
  149. if ( ! GetOptions(
  150.           'add'       => \$add,
  151.           'del'       => \$del,
  152.           'file=s'    => \$file,
  153.           'help'      => \$help,
  154.           'id=s'      => \$id,
  155.           'local=s'   => \$local,
  156.           'package=s' => \$package,
  157.           'root'      => \$root,
  158.           'type=s'    => \$type,
  159.           'verbose'   => \$verbose,
  160.           )
  161.      )
  162. {
  163.     &help;
  164.     exit 1;
  165. }
  166.  
  167.  
  168. ## ----------------------------------------------------------------------
  169. if ( defined( $help ) )
  170. {
  171.     &help;
  172.     exit -1;
  173. }
  174.  
  175. ## ----------------------------------------------------------------------
  176. if  ( ! ( defined( $add ) || defined( $del ) ) )
  177. {
  178.     print STDERR "$name: error: either 'add' or 'del' must be given\n";
  179.     exit 1;
  180. }
  181. elsif  ( ( defined( $add ) && defined( $del ) ) )
  182. {
  183.     print STDERR "$name: error: only one of 'add' and 'del' can be given\n";
  184.     exit 1;
  185. }
  186.  
  187. ## ----------------------------------------------------------------------
  188. if ( defined( $add ) )
  189. {
  190.     if ( defined( $root ) )
  191.     {
  192.     if ( defined( $package ) )
  193.     {
  194.         my $catalog = File::Spec->catfile( $catalog_dir, "$package.xml" );
  195.         if ( ! -f $catalog )
  196.         {
  197.         print STDERR "$name: error: package catalog $catalog not found\n";
  198.         exit 1;
  199.         }
  200.     }
  201.     else
  202.     {
  203.         print STDERR "$name: error: package catalog not given\n";
  204.         exit 1;
  205.     }
  206.     if ( defined( $local) || defined( $file ) )
  207.     {
  208.         print STDERR "$name: error: local catalog and file not for adding to root catalog file\n";
  209.         exit 1;
  210.     }
  211.     }
  212.     elsif ( defined( $package ) )
  213.     {
  214.     if ( defined( $local ) )
  215.     {
  216.         if ( ! -f $local )
  217.         {
  218.         print STDERR "$name: error: local catalog $local not found\n";
  219.         exit 1;
  220.         }
  221.     }
  222.     else
  223.     {
  224.         print STDERR "$name: error: local catalog not given\n";
  225.         exit 1;
  226.     }
  227.     if ( defined( $file ) )
  228.     {
  229.         print STDERR "$name: error: file not for adding to package catalog file\n";
  230.         exit 1;
  231.     }
  232.     }
  233.     elsif ( defined( $local ) )
  234.     {
  235.     if ( defined( $file ) )
  236.     {
  237.         if ( ! -f $file )
  238.         {
  239.         print STDERR "$name: error: file $file not found\n";
  240.         exit 1;
  241.         }
  242.     }
  243.     else
  244.     {
  245.         print STDERR "$name: error: file not given\n";
  246.         exit 1;
  247.     }
  248.     }
  249.     else
  250.     {
  251.     print STDERR "$name: error: catalog not given\n";
  252.     exit 1;
  253.     }
  254. }
  255. elsif ( defined( $del ) )
  256. {
  257.     if ( defined( $root ) )
  258.     {
  259.     my $catalog = File::Spec->catfile( $catalog_dir, 'catalog' );
  260.     if ( ! -f $catalog )
  261.     {
  262.         print STDERR "$name: error: root catalog $catalog not found\n";
  263.         exit 1;
  264.     }
  265.     if ( defined( $package) || defined( $local ) || defined( $file ) )
  266.     {
  267.         print STDERR "$name: error: package catalog, local catalog or file not for deleting from root catalog file\n";
  268.         exit 1;
  269.     }
  270.     }
  271.     elsif ( defined( $package ) )
  272.     {
  273.     my $catalog = File::Spec->catfile( $catalog_dir, "$package.xml" );
  274.     if ( ! -f $catalog )
  275.     {
  276.         print STDERR "$name: error: package catalog $catalog not found\n";
  277.         exit 1;
  278.     }
  279.     if ( defined( $local ) || defined( $file ) )
  280.     {
  281.         print STDERR "$name: error: local catalog or file not for deleting from package catalog file\n";
  282.         exit 1;
  283.     }
  284.     }
  285.     elsif ( defined( $local ) )
  286.     {
  287.     if ( ! -f $local )
  288.     {
  289.         print STDERR "$name: error: local catalog $local not found\n";
  290.         exit 1;
  291.     }
  292.     if ( defined( $file ) )
  293.     {
  294.         print STDERR "$name: error: file not for deleting from local catalog file\n";
  295.         exit 1;
  296.     }
  297.     }
  298.     else
  299.     {
  300.     print STDERR "$name: error: catalog not given\n";
  301.     exit 1;
  302.     }
  303. }
  304.  
  305. ## ----------------------------------------------------------------------
  306. if ( defined( $type ) )
  307. {
  308.     if ( $type !~ /^(public|system|uri)$/ )
  309.     {
  310.         print STDERR "$name: error: wrong type\n";
  311.         exit 1;
  312.     }
  313. }
  314. else
  315. {
  316.     print STDERR "$name: error: type not given\n";
  317.     exit 1;
  318. }
  319.  
  320. ## ----------------------------------------------------------------------
  321. if ( ! defined( $id ) )
  322. {
  323.     print STDERR "$name: error: id not given\n";
  324.     exit 1;
  325. }
  326.  
  327. ## ----------------------------------------------------------------------
  328. if ( defined( $root ) )
  329. {
  330.     $catalog = 'catalog';
  331.     $catalog_data = File::Spec->catfile( $catalog_data_dir, $catalog );
  332.     $catalog = File::Spec->catfile( $catalog_dir, $catalog );
  333.     my $start = $type;
  334.     $start .= 'Id' unless $type eq 'uri';
  335.     $start .= 'StartString';
  336.     $id = "$start=\"$id\"";
  337.     $type = ( $type eq 'uri' ) ? "\U$type" : "\u$type";
  338.     $type = "delegate$type";
  339.     $package = "catalog=\"file:///etc/xml/$package.xml\"";
  340.     $key = "$type $id";
  341.     $entry = "$package";
  342. }
  343. elsif ( defined( $package ) )
  344. {
  345.     $catalog_data = File::Spec->catfile( $catalog_data_dir, $package );
  346.     $catalog = File::Spec->catfile( $catalog_dir, "$package.xml" );
  347.     my $start = $type;
  348.     $start .= 'Id' unless $type eq 'uri';
  349.     $start .= 'StartString';
  350.     $id = "$start=\"$id\"";
  351.     $type = ( $type eq 'uri' ) ? "\U$type" : "\u$type";
  352.     $type = "delegate$type";
  353.     $local = "catalog=\"file://$local\"";
  354.     $key = "$type $id";
  355.     $entry = "$local";
  356. }
  357. elsif ( defined( $local ) )
  358. {
  359.     $catalog = $local;
  360.     $catalog_data = $local;
  361.     $catalog_data =~ tr|/|_|;
  362.     $catalog_data = File::Spec->catfile( $catalog_data_dir, $catalog_data );
  363.     my $start = ( $type eq 'uri' ) ? 'name' : $type;
  364.     $start .= 'Id' unless $type eq 'uri';
  365.     $id = "$start=\"$id\"";
  366.     $file = "uri=\"$file\"";
  367.     $key = "$type $id";
  368.     $entry = "$file";
  369. }
  370.  
  371. ## ----------------------------------------------------------------------
  372. if ( defined( $add ) )
  373. {
  374.     &read_catalog_data if -f $catalog_data;
  375.     if ( &add_entry )
  376.     {
  377.     &create_backup if -f $catalog;
  378.     &write_catalog_data;
  379.     &write_catalog;
  380.     }
  381.     else
  382.     {
  383.     exit 1;
  384.     }
  385. }
  386. elsif ( defined( $del ) )
  387. {
  388.     &read_catalog_data;
  389.     if ( &del_entry )
  390.     {
  391.     &create_backup;
  392.     &write_catalog_data;
  393.     &write_catalog;
  394.     }
  395.     else
  396.     {
  397.     exit 1;
  398.     }
  399. }
  400.  
  401. ## ----------------------------------------------------------------------
  402. exit 0;
  403.  
  404. ## ----------------------------------------------------------------------
  405. sub add_entry
  406. {
  407.  
  408.     ## ------------------------------------------------------------------
  409.     if ( exists( $catalog{ $key } ) )
  410.     {
  411.     if ( $catalog{ $key } ne $entry )
  412.     {
  413.         print STDERR "$name: error: entity already registered with a different value\n";
  414.         print STDERR " Entity   : [$key]\n";
  415.         print STDERR " Old value: [$catalog{$key}]\n";
  416.         print STDERR " New value: [$entry]\n";
  417.         return;
  418.     }
  419.     else
  420.     {
  421.         print STDERR "$name: notice: entity already registered\n"
  422.         if $verbose;
  423.         return 1;
  424.     }
  425.     }
  426.     else
  427.     {
  428.     print "$name: adding entity to catalog data $catalog_data with the same value\n"
  429.         if $verbose;
  430.     $catalog{ $key } = $entry;
  431.     return 1;
  432.     }
  433.  
  434. } ## add_entry
  435.  
  436. ## ----------------------------------------------------------------------
  437. sub del_entry
  438. {
  439.  
  440.     ## ------------------------------------------------------------------
  441.     if ( exists( $catalog{ $key } ) )
  442.     {
  443.     print "$name: removing entity from catalog data $catalog_data\n"
  444.         if $verbose;
  445.     delete( $catalog{ $key } );
  446.     return 1;
  447.     }
  448.     else
  449.     {
  450.     print STDERR "$name: error: entity not registered\n";
  451.     return;
  452.     }
  453.  
  454. } ## del_entry
  455.  
  456. ## ----------------------------------------------------------------------
  457. sub read_catalog_data
  458. {
  459.  
  460.     ## ------------------------------------------------------------------
  461.     print "$name: reading catalog data $catalog_data\n" if $verbose;
  462.     open( CATALOG_DATA, '<', $catalog_data )
  463.     or die "$name: cannot open catalog data $catalog_data for reading: $!";
  464.     while ( <CATALOG_DATA> )
  465.     {
  466.     chop;
  467.     my ( $key, $entry ) = split( />/ );
  468.     $key =~ s/^<//;
  469.     $entry =~ s/^<//;
  470.     $catalog{ $key } = $entry;
  471.     }
  472.     close( CATALOG_DATA )
  473.     or die "$name: cannot close catalog data $catalog_data: $!";
  474.  
  475. } ## read_catalog_data
  476.  
  477. ## ----------------------------------------------------------------------
  478. sub write_catalog_data
  479. {
  480.  
  481.     ## ------------------------------------------------------------------
  482.     print "$name: writing catalog data $catalog_data\n" if $verbose;
  483.     open( CATALOG_DATA, '>', $catalog_data )
  484.     or die "$name: cannot open catalog data $catalog_data for writing: $!";
  485.     my $counter = 0;
  486.     for my $key ( keys %catalog )
  487.     {
  488.     print( CATALOG_DATA "<$key><$catalog{ $key }>\n" );
  489.     $counter++;
  490.     }
  491.     close( CATALOG_DATA )
  492.     or die "$name: cannot close catalog data $catalog_data: $!";
  493.  
  494.     ## ------------------------------------------------------------------
  495.     if ( $counter == 0 )
  496.     {
  497.     print "$name: removing catalog data $catalog_data\n" if $verbose;
  498.     unlink( $catalog_data );
  499.     }
  500.  
  501. } ## write_catalog_data
  502.  
  503. ## ----------------------------------------------------------------------
  504. sub create_backup
  505. {
  506.  
  507.     ## ------------------------------------------------------------------
  508.     my $backup = $catalog . '.old';
  509.  
  510.     ## ------------------------------------------------------------------
  511.     if ( -f $backup )
  512.     {
  513.     print "$name: removing backup $backup\n" if $verbose;
  514.     unlink( $backup )
  515.         or die "$name: cannot remove backup $backup: $!";
  516.     }
  517.  
  518.     ## ------------------------------------------------------------------
  519.     print "$name: moving catalog $catalog to backup $backup\n" if $verbose;
  520.     rename( $catalog, $backup )
  521.     or die "$name: cannot move catalog $catalog to backup $backup: $!";
  522.  
  523. } ## create_backup
  524.  
  525. ## ----------------------------------------------------------------------
  526. sub write_catalog
  527. {
  528.  
  529.     ## ------------------------------------------------------------------
  530.     my @catalog = ();
  531.  
  532.     ## ------------------------------------------------------------------
  533.     my $header = '/usr/share/xml-core/catalog.header';
  534.     open( HEADER, '<', $header )
  535.     or die "$name: cannot open catalog header $header for reading: $!";
  536.     while ( <HEADER> )
  537.     {
  538.     chop;
  539.     push( @catalog, $_ );
  540.     }
  541.     close( HEADER )
  542.     or die "$name: cannot close catalog header $header: $!";
  543.  
  544.     ## ------------------------------------------------------------------
  545.     my $counter = 0;
  546.     for my $key ( keys %catalog )
  547.     {
  548.     push( @catalog, "<$key $catalog{ $key }/>" );
  549.     $counter++;
  550.     }
  551.  
  552.     ## ------------------------------------------------------------------
  553.     my $footer = '/usr/share/xml-core/catalog.footer';
  554.     open( FOOTER, '<', $footer )
  555.     or die "$name: cannot open catalog footer $footer for reading: $!";
  556.     while ( <FOOTER> )
  557.     {
  558.     chop;
  559.     push( @catalog, $_ );
  560.     }
  561.     close( FOOTER )
  562.     or die "$name: cannot close catalog footer $footer: $!";
  563.  
  564.     ## ------------------------------------------------------------------
  565.     print "$name: writing catalog $catalog\n" if $verbose;
  566.     open( CATALOG, '>', $catalog )
  567.     or die "$name: cannot open catalog $catalog for writing: $!";
  568.     for ( @catalog )
  569.     {
  570.     print( CATALOG $_, "\n" );
  571.     }
  572.     close( CATALOG )
  573.     or die "$name: cannot close catalog $catalog: $!";
  574.  
  575.     ## ------------------------------------------------------------------
  576.     if ( $counter == 0 )
  577.     {
  578.     print "$name: removing catalog $catalog\n" if $verbose;
  579.     unlink( $catalog );
  580.     }
  581.  
  582. } ## write_catalog
  583.  
  584. ## ----------------------------------------------------------------------
  585. sub help
  586. {
  587.  
  588.     ## ------------------------------------------------------------------
  589.     print <<END;
  590. Usage:
  591.     $name <options> --add --root --type <type> \\
  592.                                                 --id <id> --package <package>
  593.     $name <options> --del --root --type <type> \\
  594.                                                 --id <id>
  595.  
  596.     $name <options> --add --package <package> --type <type> \\
  597.                                                 --id <id> --local <local>
  598.     $name <options> --del --package <package> --type <type> \\
  599.                                                 --id <id>
  600.  
  601.     $name <options> --add --local <local> --type <type> \\
  602.                                                 --id <id> --file <file>
  603.     $name <options> --del --local <local> --type <type> \\
  604.                                                 --id <id>
  605.  
  606.     $name --help
  607.  
  608. With:
  609.     --file <file>       = a local filename
  610.     --id <id>           = catalog entry idenitifier
  611.     --local <local>     = a local XML catalog
  612.     --package <package> = a package XML catalog
  613.     --root              = the root XML catalog (= /etc/xml/catalog)
  614.     --type <type>       = catalog entry type (= public, system, uri)
  615.  
  616. Options:
  617.     --verbose = be verbose
  618.  
  619. END
  620.  
  621. } ## help
  622.  
  623. ## ----------------------------------------------------------------------
  624. __END__
  625.  
  626. ## ----------------------------------------------------------------------
  627.